package alpha.com.google.code.mechanic.janitor.model;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;

import alpha.com.google.code.mechanic.janitor.model.ContextsCollector;
import alpha.com.google.code.mechanic.janitor.model.IContext;
import alpha.com.google.code.mechanic.janitor.model.ProjectContext;

import com.google.eclipse.mechanic.tests.internal.RunAsJUnitTest;

/**
 * This is to test the class {@link ContextsCollector}.
 * 
 * @author jingjiejiang
 * @since Nov 27, 2014
 */

@RunAsJUnitTest
public class ContextsCollectorTest {
  
  private ContextsCollector contexts = new ContextsCollector(); 
  private static final String TMP_ROOT = System.getProperty("java.io.tmpdir");
  private String testDirString;
  private File testFile;
  
  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
  }

  @Before
  public void setUp() throws Exception {
    
    testDirString = TMP_ROOT + "test" + Math.random();
    
    ProjectContext mockedProjCtx_1 = Mockito.mock(ProjectContext.class);
    Mockito.when(mockedProjCtx_1.getName()).thenReturn("Context 1");
    Mockito.when(mockedProjCtx_1.getFileLocation()).thenReturn(".../Context 1");
    Mockito.when(mockedProjCtx_1.isSelected()).thenReturn(false);
    
    ProjectContext mockedProjCtx_2 = Mockito.mock(ProjectContext.class);
    Mockito.when(mockedProjCtx_2.getName()).thenReturn("Context 2");
    Mockito.when(mockedProjCtx_2.getFileLocation()).thenReturn(".../Context 2");
    Mockito.when(mockedProjCtx_2.isSelected()).thenReturn(true);
    
    ProjectContext mockedProjCtx_3 = Mockito.mock(ProjectContext.class);
    Mockito.when(mockedProjCtx_3.getName()).thenReturn("Context 3");
    Mockito.when(mockedProjCtx_3.getFileLocation()).thenReturn(".../Context 3");
    Mockito.when(mockedProjCtx_3.isSelected()).thenReturn(false);
    
    contexts.addContext(mockedProjCtx_1);
    contexts.addContext(mockedProjCtx_2);
    contexts.addContext(mockedProjCtx_3);
  }

  @After
  public void tearDown() throws Exception {
    contexts.resetContextList();
  }

  @Test
  public void testGetContextFromName() {
    assertEquals(".../Context 1", contexts.getContextFromName("Context 1").getFileLocation());
  }

  @Test
  public void testGetFileLocFromName() {
    assertEquals(".../Context 2", contexts.getFileLocFromName("Context 2"));
    assertEquals(".../Context 3", contexts.getFileLocFromName("Context 3"));
  }

  @Test
  public void testDelSelContext() {
    contexts.delSelContext();
    //assertNull(contexts.getSelContext());
    assertNull(contexts.getContextFromName("Context 2"));
  }

  @Test
  public void testGetSelContext() {
    assertEquals("Context 2", contexts.getSelContext().getName());
    assertNotSame("Context 3", contexts.getSelContext().getName());
  }

  @Test
  public void testGetCtxNameList() {
    List<String> ctxnames = contexts.getCtxNameList();
    assertEquals(3, ctxnames.size());
    assertEquals("Context 1", ctxnames.get(0));
  }

  @Test
  public void testIsValidCtxName() {
    assertFalse(contexts.isValidCtxName("Context 3"));
    assertTrue(contexts.isValidCtxName("Context 4"));
  }

  @Test
  public void testSerializeAndDeserializeContextsInfo() throws Exception {
    
    contexts.serializeContextsInfo(testFile);
    ProjectContext context = null;
    
    for (int i = 0; i < 3; i++) {
      
      IContext curctx = contexts.deserializeContextInfo(testFile, i, context);
      if (0 == i) {
        assertEquals("Context 1", curctx.getName());
      }
      
      if(1 == i) {
        assertEquals("Context 2", curctx.getName());
        return;
      }
    }
  }

  @Test
  public void testGetSavedCollectorSize() throws IOException {
    
    initContextInfoFile();
    contexts.serializeContextsInfo(testFile);
    
    assertEquals(3, contexts.getSavedCollectorSize(testFile));
  }

  private void initContextInfoFile(){
    
    File dir = new File(testDirString);
    if (false == dir.mkdir()) {
      fail("Couldn't create file: " + testDirString);
    }else {
      testFile = new File (dir + File.separator + "text.con");
    }
  }
}
